package com.xiguanlezz.cn.scanner;

import com.xiguanlezz.cn.ScannerConst;

import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * @Author：习惯了种种
 * @CreateDate：2024/11/2 23:56
 * @Description：自定义扫描器，用于扫描RpcService和RpcReference
 */
public class ClassScanner implements ScanPackageClassAbility, ScanJarClassAbility {

    private static final ScanPackageClassAbility scanPackageClassProcessor = new BaseScanPackageClassProcessor();

    private static final ScanJarClassAbility scanJarClassProcessor = new BaseScanJarClassProcessor();


    @Override
    public void scanAndAddClassesInJar(String packagePath, URL url, List<String> classNameList) {
        scanJarClassProcessor.scanAndAddClassesInJar(packagePath, url, classNameList);
    }

    @Override
    public void scanAndAddClassesInPackage(String scanPath, String packagePath, String packageName, List<String> classNameList) {
        scanPackageClassProcessor.scanAndAddClassesInPackage(scanPath, packagePath, packageName, classNameList);
    }

    protected static List<String> getClassNameList(String packageName) throws IOException {
        return getClassNameList(packageName, true);
    }

    private static List<String> getClassNameList(String packageName, boolean getResources) throws IOException {
        List<String> classNameList = new ArrayList<>();
        String packagePath = packageName.replace(".", "/");

        if (getResources) {
            // 使用java.lang.ClassLoader.getResources方法获取资源文件
            Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packagePath);
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                String protocol = url.getProtocol();
                // 这里为什么需要分支区分jar还是file？因为如果packageName指定的就是jar包需要单独处理
                if (ScannerConst.PROTOCOL_FILE.equals(protocol)) {
                    scanPackageClassProcessor.scanAndAddClassesInPackage(URLDecoder.decode(url.getPath(), "UTF-8"), packagePath, packageName, classNameList);
                } else {
                    scanJarClassProcessor.scanAndAddClassesInJar(packagePath, url, classNameList);
                }
            }
        } else {
            // 使用java.lang.ClassLoader.getResource方法获取资源文件
            URL url = Thread.currentThread().getContextClassLoader().getResource(packagePath);
            String protocol = url.getProtocol();
            // 这里为什么需要分支区分jar还是file？因为如果packageName指定的就是jar包需要单独处理
            if (ScannerConst.PROTOCOL_FILE.equals(protocol)) {
                scanPackageClassProcessor.scanAndAddClassesInPackage(URLDecoder.decode(url.getPath(), "UTF-8"), packagePath, packageName, classNameList);
            } else {
                scanJarClassProcessor.scanAndAddClassesInJar(packagePath, url, classNameList);
            }
        }
        return classNameList;
    }
}
